/*
 * WAI2008
 * localizadorWAI.h
 *
 *  Created on: Oct 2, 2008
 *      Author: Milton Yukio Godoy Saito
 */

#ifndef LOCALIZADORWAI_H_
#define LOCALIZADORWAI_H_

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

#include <mysql++.h>
#include <pthread.h>

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <iomanip>

#include "ServerSocket.h"
#include "SocketException.h"



#define RSSI_MAX 	96
#define RSSI_MIN 	0
#define Beta     	0.0001
#define NMAXUSUARIOS    30

#define FLOOR    1

#define PI       3.14159265

#define PPC      0.95

#define N_PM 		100 // número dos Pontos de Medida
#define N_PA     	20 // número dos Pontos de Acesso
#define BANCO_DE_DADOS  "radiomap_bartira" // nome do banco de dados onde serão gravados os dados
#define	SERVER_PORT	30000

#define FAKE_INPUT	"<SSProtocol><HDSerial>12345678</HDSerial><Network><ID>00:0F:3D:38:3F:85</ID><Signal>-81</Signal></Network></SSProtocol>"


struct SWorkingThread
{
  ServerSocket* m_pSocket;
  int n_thread;

  SWorkingThread(ServerSocket* pSocket,
		 int _n_thread)
  {
    m_pSocket  = pSocket;
    n_thread= _n_thread;
  }
  ~SWorkingThread()
  {
    delete m_pSocket;
  }
};


struct coordenada {
  float x;
  float y;
} xy;

// estrutura a ser carregada a partir do BD
struct ponto_medida {
  int floor;
  float x;
  float y;
} PM[N_PM];


// estrutura a ser carregada a partir do BD
struct ponto_acesso {
  int id;
  char ssid[30];
} PA[N_PA];

// fake para simular coleta de dados do Driver Wireless
struct scan {
  int hdSerial;
  int sinal[N_PA];
};


struct ppm_ant {
  int hdSerial;
  double Ppm_ant[N_PM];
}probAntByUser[NMAXUSUARIOS];


struct histograma {
#define N_BARRAS 60
  int total;
  int presente;
  float media;
  float desvio;
  int h[N_BARRAS];
}H[N_PM][N_PA];

#ifndef VITERBI
struct celula {
  int id;
  int n_arestas;
};
struct celula 		Cel_Adj[N_PM][10];
#else
int	 		Cel_Adj[N_PM][10];
#endif
int 			n_Cel_Adj[N_PM];


// estrutura para tratamento de ruídos
double HR[RSSI_MAX];
double HR_count;
int mascara_PAs[N_PM][N_PA];

double Ppm[N_PM];
int    valido[N_PA];
double Ppm_ant[N_PM];
int nUsuarios;


mysqlpp::Connection con(false);
mysqlpp::Query query=NULL;
mysqlpp::Result  res2;
mysqlpp::Result  res3;


/*
 * The standard normal CDF, for one random variable.
 *
 *   Author:  W. J. Cody
 *   URL:   http://www.netlib.org/specfun/erf
 *
 * This is the erfc() routine only, adapted by the
 * transform stdnormal_cdf(u)=(erfc(-u/sqrt(2))/2;
 */
double stdnormal_cdf(double u)
{
 const double a[5] = {
  1.161110663653770e-002,3.951404679838207e-001,2.846603853776254e+001,
  1.887426188426510e+002,3.209377589138469e+003
 };
 const double b[5] = {
  1.767766952966369e-001,8.344316438579620e+000,1.725514762600375e+002,
  1.813893686502485e+003,8.044716608901563e+003
 };
 const double c[9] = {
  2.15311535474403846e-8,5.64188496988670089e-1,8.88314979438837594e00,
  6.61191906371416295e01,2.98635138197400131e02,8.81952221241769090e02,
  1.71204761263407058e03,2.05107837782607147e03,1.23033935479799725E03
 };
 const double d[9] = {
  1.00000000000000000e00,1.57449261107098347e01,1.17693950891312499e02,
  5.37181101862009858e02,1.62138957456669019e03,3.29079923573345963e03,
  4.36261909014324716e03,3.43936767414372164e03,1.23033935480374942e03
 };
 const double p[6] = {
  1.63153871373020978e-2,3.05326634961232344e-1,3.60344899949804439e-1,
  1.25781726111229246e-1,1.60837851487422766e-2,6.58749161529837803e-4
 };
 const double q[6] = {
  1.00000000000000000e00,2.56852019228982242e00,1.87295284992346047e00,
  5.27905102951428412e-1,6.05183413124413191e-2,2.33520497626869185e-3
 };
 register double y, z;


 y = fabs(u);
 if (y <= 0.46875*sqrt(2)) {
  /* evaluate erf() for |u| <= sqrt(2)*0.46875 */
  z = y*y;
  y = u*((((a[0]*z+a[1])*z+a[2])*z+a[3])*z+a[4])
       /((((b[0]*z+b[1])*z+b[2])*z+b[3])*z+b[4]);

  return 0.5+y;
 }
 z = exp(-y*y/2)/2;
 if (y <= 4.0*sqrt(2)) {
  /* evaluate erfc() for sqrt(2)*0.46875 <= |u| <= sqrt(2)*4.0 */
  y = y/sqrt(2);
  y = ((((((((c[0]*y+c[1])*y+c[2])*y+c[3])*y+c[4])*y+c[5])*y+c[6])*y+c[7])*y+c[8])
     /((((((((d[0]*y+d[1])*y+d[2])*y+d[3])*y+d[4])*y+d[5])*y+d[6])*y+d[7])*y+d[8]);

  y = z*y;
 } else {
  /* evaluate erfc() for |u| > sqrt(2)*4.0 */
  z = z*sqrt(2)/y;
  y = 2/(y*y);
  y = y*(((((p[0]*y+p[1])*y+p[2])*y+p[3])*y+p[4])*y+p[5])
       /(((((q[0]*y+q[1])*y+q[2])*y+q[3])*y+q[4])*y+q[5]);
  y = z*(sqrt(PI)-y);

 }
 //return 3;
 return (u < 0.0 ? y : 1-y);
};



double normal_cdf(double media, double desvio, double x){
  // return (1+erf((x-media)/(desvio*sqrt(PI))))/2;
  return stdnormal_cdf((x-media)/(desvio));
}


double normal_integral(double media, double desvio, double a, double b){
  if (a > b){
    double c = b;
    b = a;
    a = c;
  }
  return normal_cdf(media, desvio, b) - normal_cdf(media, desvio, a);
}


#endif /* LOCALIZADORWAI_H_ */
